﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PessModel;
using System.Web.Security;

namespace PessMvc.Controllers
{
    public class GradeRuleController : Controller
    {
        PESSEntities db;
        public GradeRuleController()
        {
            db = new PESSEntities();
        }
        // GET: GradeRule
        public ActionResult Index(int activityID)
        {
            var activity = db.Activities.Find(activityID);
            var subjects = activity.Subjects;
            string userName = Membership.GetUser().UserName;
            if (Roles.IsUserInRole(Membership.GetUser().UserName, "ExpertJudge"))
            {
                var expertJudge = db.ExpertJudges.Find(userName);

                var subjectIDs = (from eg in expertJudge.ExpertGroups
                                  join a in db.Archives on eg.ActivityID equals a.Subject.ActivityID
                                  where eg.ActivityID == activityID
                                  select a.SubjectID).Distinct();
                subjects = subjects.Where(s => subjectIDs.Contains(s.ID)).ToList();
            }
            ViewBag.IsGradeRulesEnabled = activity.IsGradingRulesEnabled;
            ViewBag.ActivityID = activityID;
            return View(subjects);
        }
        public ActionResult Details(int subjectID)
        {
            var subject = db.Subjects.Find(subjectID);
            ViewData["TargetSubjectID"] = subjectID;
            var gradeRules = subject.GradeRules;            
            int activityID = subject.ActivityID;
            ViewBag.SubjectName = subject.Name;
            ViewBag.ActivityID = activityID;
            ViewBag.SubjectID = new SelectList(db.Subjects.Where(s => s.ActivityID == activityID && s.Name != subject.Name), "ID", "Name");

            //Show or hide the create new rule button.
            MembershipUser user = Membership.GetUser();
            var expertJudge = db.ExpertJudges.Find(user.UserName);
            ViewBag.ShowCreateRuleButton = false;            
            if (Roles.IsUserInRole("Admin"))
            {
                ViewBag.ShowCreateRuleButton = true;
            }
            //gradeRules=gradeRules.OrderBy(g => g.Percentage);
            return View(gradeRules.OrderBy(g=>g.Name));
        }
        [Authorize(Roles = "Admin")]
        public ActionResult Create(int subjectID)
        {
            ViewBag.SubjectID = subjectID;
            return View();
        }
        [HttpPost]
        [Authorize(Roles = "Admin")]
        public ActionResult Create(GradeRule gradeRule)
        {
            ViewBag.SubjectID = gradeRule.SubjectID;
            if (ModelState.IsValid)
            {
                string errorMsg = "";
                //Make sure the total percentage should be equal or less than 100 percent. Other wise it makes no sense.
                if (db.Subjects.Find(gradeRule.SubjectID).GradeRules.Sum(r => r.Percentage) + gradeRule.Percentage <= 100)
                {
                    if (gradeRule.Ceiling >= gradeRule.Floor)
                    {
                        db.GradeRules.Add(gradeRule);
                        db.SaveChanges();
                        return RedirectToAction("Details", new { subjectID = gradeRule.SubjectID });
                    }
                    else
                    {
                        errorMsg = "Ceiling should not be less than floor!";
                    }
                }
                else
                {
                    errorMsg += "\r\n" + "Total percentage exceeds 100.";                    
                }

                if(errorMsg!="")
                {
                    ModelState.AddModelError("", errorMsg);
                }
            }            
            //else
            //{
            //    return View(gradeRule);
            //}
            return View(gradeRule);
        }
        [Authorize(Roles ="Admin")]
        public ActionResult Edit(int gradeRuleID)
        {
            return View(db.GradeRules.Find(gradeRuleID));
        }
        [HttpPost]
        [Authorize(Roles = "Admin")]
        public ActionResult Edit(GradeRule gradeRule)
        {
            if(ModelState.IsValid)
            {
                db.Entry(gradeRule).State = System.Data.Entity.EntityState.Modified;
                db.SaveChanges();

                return RedirectToAction("Details", new { subjectID = gradeRule.SubjectID });
            }
            return View(gradeRule);
        }
        [Authorize(Roles = "Admin")]
        public ActionResult Delete(int gradeRuleID)
        {
            return View(db.GradeRules.Find(gradeRuleID));
        }

        [HttpPost, ActionName("Delete")]
        [Authorize(Roles = "Admin")]
        public ActionResult DeleteConfirmed(int gradeRuleID)
        {
            var gradeRule = db.GradeRules.Find(gradeRuleID);
            int subjectID = gradeRule.SubjectID;
            if (gradeRule.Grades.Count == 0)
            {
                db.GradeRules.Remove(gradeRule);
                db.SaveChanges();
                return RedirectToAction("Details", new { subjectID = subjectID });
            }
            else
            {
                return RedirectToAction("Delete", new { ruleID = gradeRuleID });
            }
        }
        [HttpPost]
        [Authorize(Roles = "Admin")]
        public ActionResult CopyGradeRulesFromSubject(int targetSubjectID, int subjectID)
        {
            var targetSubject = db.Subjects.Find(targetSubjectID);
            var sourceSubject = db.Subjects.Find(subjectID);
            if (targetSubject != null && sourceSubject != null //Target and source subject both exist.
                && targetSubject.ActivityID == sourceSubject.ActivityID //under the same activity.
                && targetSubject.GradeRules.Count == 0 //target has no rules.
                && sourceSubject.GradeRules.Count > 0) //source has rules.
            {
                var sourceRules = from r in sourceSubject.GradeRules
                                  select new PessModel.GradeRule() { Name = r.Name, Description = r.Description,
                                      SubjectID = targetSubjectID, ValidationRequired=r.ValidationRequired, Ceiling=r.Ceiling, Floor=r.Floor, Percentage=r.Percentage };
                foreach (var r in sourceRules)
                {
                    db.GradeRules.Add(r);
                }
                db.SaveChanges();                
            }
            return RedirectToAction("Details", "GradeRule", new { subjectID = targetSubjectID });
        }
    }
}